import store from '@/store/index.js'
let _self;
export default class deviceClass {
	constructor() {
		_self = this
		_self.deviceId = ""
		_self.isConnect = false //是否已连接
		_self.isStop = false //是否停止搜所
		_self.BLUE_NAME = uni.getStorageSync('BLUE_NAME') // 蓝牙名字
		// _self.BLUE_NAME = 'B2' // 蓝牙名字
		_self.UUID_SERVICE = uni.getStorageSync('UUID_SERVICE') //服务UUID，设备方提供
		_self.UUID_CHAR = uni.getStorageSync('UUID_CHAR') //特征值UUID，设备方提供
		_self.timer = null
	}
	reset(mac) {
		_self = this
		_self.deviceId = ""
		_self.isConnect = false //是否已连接
		_self.isStop = false //是否停止搜所
		_self.initEventDevice(mac)
		_self.BLUE_NAME = mac // 蓝牙名字

	}
	/* 初始化并搜索蓝牙操作 */
	initEventDevice(mac) {
		if (store.getters.bluetoothStatus) {
			return
		}
		console.log(111111)

		_self.BLUE_NAME = mac // 蓝牙名字
		/* 1、初始化蓝牙 uni.openBluetoothAdapter(OBJECT) */
		uni.openBluetoothAdapter({
			complete: () => {
				/* 监听蓝牙是否开启*/
				uni.onBluetoothAdapterStateChange(function(res) {
					//res.available 蓝牙适配器是否可用
					//res.discovering 蓝牙适配器是否处于搜索状态
					// console.log('适配器状态变化', res)
					console.log(_self.isStop)
					if (!res.available && !res.discovering) {
						_self.isStop = false;
						uni.showToast({
							duration: 2500,
							title: "请打开手机蓝牙",
							icon: 'error',
						})
						store.commit('user/UPDATE_STATUS', false);
					} else if (_self.isStop == false && res.available && !res.discovering && res
						.connected == false) {
						console.log("蓝牙已开启，可以执行搜索操作")
						_self.initEventDevice(mac);
					} else if (res.available && res.discovering) {
						// console.log("蓝牙已开启，并且正在搜索中")
					}
				})
			},
			success: (res) => {
				/* 初始化蓝牙成功 */
				/* 2、开始搜索蓝牙设备 uni.startBluetoothDevicesDiscovery(OBJECT) */
				/* 监听蓝牙适配器状态变化事件  可以检测当前设备的蓝牙的断开或者连接的情况*/
				// console.log('res********'  + JSON.stringify(res))

				_self.startBluetoothDevicesDiscovery();
				_self.connectTimeout();

			},
			fail: (res) => {
				// console.log("初始化蓝牙失败:" + JSON.stringify(res))
				uni.hideLoading();
				uni.showToast({
					duration: 2500,
					title: "请打开手机蓝牙",
					icon: 'error',
				})
			}
		})
	}


	/*搜索蓝牙*/
	startBluetoothDevicesDiscovery() {
		uni.getBluetoothDevices({
			success(res) {
				uni.startBluetoothDevicesDiscovery({
					allowDuplicatesKey: false, //是否允许同一设备多次上报，但RSSI值会有所不同
					// interval:50,
					powerLevel: 'high',
					success: (res) => {
						console.log("搜索成功:" + JSON.stringify(res))
						console.log('11111')
						_self.onBluetoothDeviceFound();
					},
					fail: (res) => {
						console.log('搜索蓝牙设备失败，错误码：' + JSON.stringify(res));
						uni.hideLoading();
						let content = "1、请确认是否开启手机蓝牙\n2、请关闭蓝牙再次扫码连接\n3、请确认手机位置已经打开\n4、删除小程序重新扫码进入"
						
						uni.showModal({
							title: '蓝牙连接失败了哦',
							content: content,
							showCancel: false,
							confirmText: "我知道了",
							success: () => {
								//_self.reset()
							}
						})
						// console.log("搜索失败:" + JSON.stringify(res))
					}
				})
			},
			fail: function(err) {
				uni.hideLoading();
				that.Log(err, "搜索蓝牙-失败");
				var message = "请稍后再试";
				if (err.errCode == 10000) {
					message = "请确认蓝牙是否已连接";
				} else if (err.errCode == 10001) {
					message = "请确认蓝牙是否已开启";
				}
				errfun(message);
			},
		});

	}

	/* 搜索蓝牙设备回调 */
	onBluetoothDeviceFound() {
		uni.onBluetoothDeviceFound(res => {
			uni.showLoading({
				title: "蓝牙连接中",
				mask: true
			})
			let baseMmac = 'B' + _self.BLUE_NAME
			// console.log(res.devices[0].localName, res.devices[0].deviceId)
			let des = res.devices[0];
			if (baseMmac == des.localName || baseMmac == des.name) {
				console.log(des.localName, des.name)
				console.log('找到设备')

				_self.isStop == true
				_self.isConnect = true;
				_self.stopBluetoothDevicesDiscovery()
				_self.connectDevice(des.deviceId);


			}
		})
	}

	/*设置蓝牙搜索时间30秒, 如果超时没有搜索到就停止搜索*/
	connectTimeout() {
		_self.timer = setTimeout(() => {
			if (!_self.isConnect) {
				uni.hideLoading();
				_self.stopBluetoothDevicesDiscovery();
				let content = "1、请确认是否开启手机蓝牙\n2、请关闭蓝牙再次扫码连接\n3、请确认手机位置已经打开\n4、删除小程序重新扫码进入"
				
				uni.showModal({
					title: '蓝牙连接失败了哦',
					content: content,
					showCancel: false,
					confirmText: "我知道了",
					success: () => {
						// _self.reset()
					}
				})
			}
		}, 30000)
	}

	/* 停止搜索 */
	stopBluetoothDevicesDiscovery() {
		uni.stopBluetoothDevicesDiscovery({
			complete: () => {
				_self.isStop = true;
				clearTimeout(_self.timer)
			},
			success: (res) => {
				_self.isStop = true;
				console.log("停止搜索成功")
			},
			fail: (res) => {
				// console.log("停止失败")
				uni.hideLoading();
			}
		})
	}

	/* 连接低功耗蓝牙 */
	connectDevice(deviceId) {
		console.log("执行到这里了", deviceId)
		uni.createBLEConnection({
			deviceId, //点击的DeviceId
			timeout: 5000,
			success: (res) => {

				console.log("连接成功")
				_self.deviceId = deviceId;
				uni.setStorageSync('deviceId', deviceId)
				/* 这边获取全部的服务，并筛选出当前需要的*/
				_self.getBLEDeviceServices(deviceId)

			},
			fail: (error) => {
				/* 连接失败 */
				uni.hideLoading();
				// console.log("连接失败")
				console.log(error);
				let content = "1、请确认是否开启手机蓝牙\n2、请关闭蓝牙再次扫码连接\n3、请确认手机位置已经打开\n4、删除小程序重新扫码进入"
				
				uni.showModal({
					title: '蓝牙连接失败了哦',
					content: content,
					showCancel: false,
					confirmText: "我知道了",
					success: () => { // _self.reset()
					}
				})
			}
		})
		/* 监听蓝牙设备的连接状态 */
		uni.onBLEConnectionStateChange(function(res) {
			// console.log(res.deviceId + "连接状态:" + res.connected)
		})
	}

	/* 获取所有的服务*/
	getBLEDeviceServices(deviceId) {
		// console.log("开始获取服务")
		//连接成功之后需要延时，继续操作才不会出问题,延时时间短一点都没关系，我这边用了1秒
		setTimeout(() => {
			uni.getBLEDeviceServices({
				// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
				deviceId,
				success: (res) => {
					console.log(res)
					// console.log('device services:', res)
					res.services.forEach((item) => {
						//这里微信小程序获取的服务ID是大写，支付宝是小写，所以统一转换为大写
						let serviceId = item.uuid.toUpperCase();
						uni.setStorageSync('ServiceId', item.uuid.toUpperCase())
						console.log(serviceId, _self.UUID_SERVICE)
						if (serviceId == _self.UUID_SERVICE) {
							// console.log('serverId:', serviceId)
							/* 进入特征值 */
							console.log(111)
							_self.getBLEDeviceCharacteristics(deviceId, serviceId);
						}
					})
				},
				fail: (error) => {
					// console.log("获取服务失败")
					// console.log(error)
					uni.hideLoading();
				}
			})
		}, 200)
	}

	/* 获取所有特征值 */
	getBLEDeviceCharacteristics(deviceId, serviceId) {
		// console.log("开始获取特征")
		setTimeout(() => {
			uni.getBLEDeviceCharacteristics({
				deviceId,
				serviceId,
				success: (res) => {
					console.log(res, ">>>>>所有特征值")
					// res.characteristics.forEach((item) => {
					// console.log(item, ">>>>>每一条")
					//这里跟服务ID一样，支付宝需要转换为大写
					//#ifdef MP-ALIPAY
					// let characterId = item.characteristicId.toUpperCase();
					//#endif
					//#ifdef MP-WEIXIN
					// let characterId = item.uuid;
					//#endif

					// 存储可写特征值
					// if (item.properties.write) {
					// 	console.log(item.uuid, item.properties.write,
					// 		'>>>>>>>存储可写特征值')
					uni.setStorageSync('UUID_CHAR_WRITE',
						'00010203-0405-0607-0809-0A0B0C0D2B11'
					) //特征值UUID，设备方提供
					// }

					_self.notifyBLECharacteristicValueChange(deviceId, serviceId,
						_self
						.UUID_CHAR)
					/* 只要用到的唤醒即可 */
					// console.log(characterId, _self.UUID_CHAR, '>>>>>>条件')
					// if (characterId == _self.UUID_CHAR) {
					//     // console.log('characteristicId:', characterId)
					//     _self.notifyBLECharacteristicValueChange(deviceId, serviceId, characterId)
					// }

					// })
				},
				fail: (res) => {
					uni.hideLoading();
					// console.log(res)
				}
			})
		}, 200)
	}
	/* 启用蓝牙设备特征值变化时的 notify 功能 */
	notifyBLECharacteristicValueChange(deviceId, serviceId, characteristicId) {
		// console.log("开始唤醒")
		console.log(deviceId, serviceId, characteristicId, 'notifyBLECharacteristicValueChange');
		uni.notifyBLECharacteristicValueChange({
			state: true, // 启用 notify 功能
			// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
			deviceId,
			// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
			serviceId,
			// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
			characteristicId,
			success: (res) => {
				uni.hideLoading();
				/* 连接成功 */
				uni.showToast({
					title: "连接成功",
					icon: 'success'
				});
				//储存蓝牙连接状态
				console.log(111111)
				store.commit('user/UPDATE_STATUS', true);

				// console.log('notifyBLECharacteristicValueChange success', res.errMsg)
				/* 连接成功以后，执行设置的操作，并且打开返回值的监听开关并监听 */
				//获取设备信息
				//             let DeviceCommand = "01,02,03,04," + _self.func("01020304") + ",1E";
				// console.log(DeviceCommand);
				//             let DeviceArrayBuffer = _self.string2buffer(DeviceCommand);
				// 			console.log(DeviceArrayBuffer);
				_self.onBLECharacteristicValueChange();
				//同步设备信息
				let DeviceCommand = '&voltage';
				_self.writeDevice(DeviceCommand);

				//出货后关门延时设置
				// let delayedCommand = "01,02,03,04,0A," + _self.func("010203040A") + ",1E";
				// let delayedArrayBuffer = _self.string2buffer(delayedCommand);
				// _self.writeDevice(delayedArrayBuffer);

				/* 监听低功耗蓝牙设备的特征值变化 */
				//     uni.onBLECharacteristicValueChange(function(CALLBACK) {
				//         let result = blueTool.ab2hex(CALLBACK.value);
				//         // console.log("收到的数据值==", result);
				//         // 这里做一些具体的业务逻辑
				//         //我这里是监听低功耗蓝牙设备的特征值变化，然后调后台接口获取设备的电量，展示在页面
				//         if ("73080182" === result.substring(0, 8)) {
				//             var o = result.substring(8, 10);
				//             o = parseInt(o, 16);
				//             let dl = "";
				//             if (o >= 41) {
				//                 dl = 100;
				//             } else if (o <= 37) {
				//                 dl = 0;
				//             } else {
				//                 dl = (o - 37) * 100 / (41 - 37);
				//             }
				//             //获取设备电量
				//             uni.request({
				//                 url:  baseUrl+"/api/*****",
				//                 method: "POST",
				//                 data: {
				//                     key: value
				//                 },
				//                 header: {
				//                     "Content-Type": "application/x-www-form-urlencoded"
				//                 },
				//                 success: function(t) {
				//                     // store.commit('setDeviceBattery', t.data.data);
				//                     // console.log("设备上传回调" + JSON.stringify(t.data));
				//                 },
				//                 fail: function(t) {}
				//             });
				//         }
				//     })
			},
			fail: (res) => {
				uni.hideLoading();
				// console.log('notifyBLECharacteristicValueChange success', res.errMsg)
			}
		})
	}

	onBLECharacteristicValueChange() {
		uni.onBLECharacteristicValueChange((res) => {
			console.log(res, '接收蓝牙通知==>>>onBLECharacteristicValueChange');
			if (res.command == '&voltage') {
				res.syscmd = this._bufferToHexadecimal(res.value);
			} else {
				try {
					//在此运行代码
					let unit8Arr = new Uint8Array(res.value);
					let encodedString = String.fromCharCode.apply(null, unit8Arr);
					let decodedString = decodeURIComponent(escape((encodedString))); //没有这一步中文会乱码
					let syscmd = decodedString.replace(/[\u]/g, '').replace(/[\n]/g, '');
					let strArr = syscmd.match(/\<.*?\>/g);

					if (strArr) {
						res.syscmd = syscmd;
						syscmd = '';
					} else {
						res.syscmd = syscmd;
					}
				} catch (err) {
					res.syscmd = this._bufferToHexadecimal(res.value);
					console.log(err, '蓝牙解密错误');
					//在此处理错误
				}
			}

			console.log(res.syscmd, '蓝牙解密指令=》》》》');
		})
	}




	/**
	 * 字符串转16进制
	 * @param {String} str 字符串
	 * @callback  {Buffer} 将数组变成buffer
	 */
	_stringToHexadecimal(str) {
		let val = '';
		for (let i = 0; i < str.length; i++) {
			if (val === '') {
				val = str.charCodeAt(i).toString(16);
			} else {
				val += ',' + str.charCodeAt(i).toString(16);
			}
		}
		return val;
	}

	/**
	 * 16进制转arrayBuffer
	 * @param {String} str 字符串
	 * @callback  {Buffer} 将数组变成buffer
	 */
	_hexadecimalToBuffer(str) {
		return new Uint8Array(
			str.match(/[\da-f]{2}/gi).map(function(h) {
				return parseInt(h, 16);
			})
		).buffer;
	}
	/**
	 * arrayBuffer转16进制
	 * @param {Buffer} buffer 数据buffer对象
	 * @callback {Array} hexArr 数据16进制数组
	 */
	_bufferToHexadecimal(buffer) {
		const hexArr = Array.prototype.map.call(new Uint8Array(buffer), function(bit) {
			return ('00' + bit.toString(16)).slice(-2);
		});
		return hexArr;
	}
	/* 执行写入命令操作 */
	writeDevice(cmd) {
		let sendCmd = cmd.toString(); //发送命令
		let bytes = sendCmd.length; //命令字节长度
		let cmdBuffer = ''; //发送命令字节
		console.log('开始发送蓝牙指令', sendCmd, '指令长度', sendCmd.length, '指令类型', typeof cmd)

		for (let i = 0; i < bytes; i += 20) {
			if (typeof cmd == 'number') {
				cmdBuffer = cmd;
				console.log('接受到数字指令', cmd);
			} else {
				if (i + 20 < bytes) {
					cmdBuffer = sendCmd.slice(i, i + 20);
				} else {
					cmdBuffer = sendCmd.slice(i, bytes);
				}
			}

			let value = _self._stringToHexadecimal(cmdBuffer)
			console.log('命令16进制', cmdBuffer, value);
			setTimeout(() => {
				console.log(_self, "_self");
				console.log(uni.getStorageSync('deviceId'), "uni.getStorageSync('deviceId')");
				console.log(_self.deviceId, "_self.deviceId");
				console.log(_self.UUID_SERVICE, "_self.UUID_SERVICE");
				console.log(uni.getStorageSync('UUID_CHAR_WRITE'), "uni.getStorageSync('UUID_CHAR_WRITE')");
				console.log(_self._hexadecimalToBuffer(value),'value');
				uni.writeBLECharacteristicValue({
					deviceId: uni.getStorageSync('deviceId'),
					serviceId: _self.UUID_SERVICE,
					characteristicId: uni.getStorageSync('UUID_CHAR_WRITE'),
					value: _self._hexadecimalToBuffer(value),
					success: (res) => {
						console.log('发送蓝牙写入指令成功:' + i, res, '发送的指令:', sendCmd);


					},
					fail: (err) => {
						if (err.errCode == 10008) {
							uni.writeBLECharacteristicValue({
								deviceId: _self.deviceId,
								serviceId: _self.UUID_SERVICE,
								characteristicId: uni.getStorageSync('UUID_CHAR_WRITE'),
								value: _self._hexadecimalToBuffer(value),
								success: (res) => {
									console.log('发送蓝牙写入指令成功:' + i, res, '发送的指令:',
										sendCmd);
								},
							})
						}
						console.log('发送蓝牙写入指令失败:' + i, err, '发送的指令:', sendCmd);


					}
				})
			}, 5)
		}

		// let buffer = _self.hexStringToArrayBuffer(msg);
		// let pos = 0;
		// let bytes = buffer.byteLength;
		// console.log("bytes", bytes)
		// console.log(uni.getStorageSync('UUID_CHAR_WRITE'), '>>>>>写入的特征值')
		// while (bytes > 0) {
		//     let tmpBuffer;
		//     if (bytes > 20) {
		//       return _self.delay(0.3).then(() => {
		//         tmpBuffer = buffer.slice(pos, pos + 20);
		//         pos += 20;
		//         bytes -= 20;
		//         console.log("tmpBuffer", tmpBuffer)
		//         uni.writeBLECharacteristicValue({
		//             deviceId: _self.deviceId,
		//             serviceId: _self.UUID_SERVICE,
		//             characteristicId: uni.getStorageSync('UUID_CHAR_WRITE'),
		//             value: tmpBuffer,
		//             success: (res) => {
		//         		// uni.showToast({
		//         		// 	title: '操作成功，请取货！',
		//         		// 	icon: 'success',
		//         		// 	duration: 3000
		//         		// })
		//                 /* 发送成功 */
		//                 console.log('第一次发送成功', res)
		//             },
		//             fail: (error) => {
		//                 /* 发送失败 */
		//                 console.log('第一次写入失败', error)
		//             }
		//         })
		//       })
		//     } else {
		//      return  _self.delay(0.3).then(() => {
		//         tmpBuffer = buffer.slice(pos, pos + bytes);
		//         pos += bytes;
		//         bytes -= bytes;
		// 		uni.writeBLECharacteristicValue({
		// 		    deviceId: _self.deviceId,
		// 		    serviceId: _self.UUID_SERVICE,
		// 		    characteristicId: uni.getStorageSync('UUID_CHAR_WRITE'),
		// 		    value: tmpBuffer,
		// 		    success: (res) => {
		// 				uni.showToast({
		// 					title: '操作成功，请取货！',
		// 					icon: 'success',
		// 					duration: 3000
		// 				})
		// 		        /* 发送成功 */
		// 		        console.log('最后一次发送成功', res)
		// 		    },
		// 		    fail: (error) => {
		// 		        /* 发送失败 */
		// 		        console.log('最后一次写入失败', error)
		// 		    }
		// 		})
		//       })
		//     }
		//   }

		// let buffer = new ArrayBuffer(_Buffer)
		//          uni.writeBLECharacteristicValue({
		//              deviceId: _self.deviceId,
		//              serviceId: _self.UUID_SERVICE,
		//              characteristicId: uni.getStorageSync('UUID_CHAR_WRITE'),
		//              value: buffer,
		//              success: (res) => {
		// 		uni.showToast({
		// 			title: '操作成功，请取货！',
		// 			icon: 'success',
		// 			duration: 3000
		// 		})
		//                  /* 发送成功 */
		//                  console.log('最后一次写入成功', res)
		//              },
		//              fail: (error) => {
		//                  /* 发送失败 */
		//                  console.log('最后一次写入失败', error)
		//              }
		//          })
	}

	hexStringToArrayBuffer(str) {
		if (!str) {
			return new ArrayBuffer(0);
		}
		var buffer = new ArrayBuffer(str.length);
		let dataView = new DataView(buffer)
		let ind = 0;
		for (var i = 0, len = str.length; i < len; i += 2) {
			let code = parseInt(str.substr(i, 2), 16)
			dataView.setUint8(ind, code)
			ind++
		}
		return buffer;
	}

	delay(ms, res) {
		return new Promise(function(resolve, reject) {
			setTimeout(function() {
				resolve(res);
			}, ms);
		});
	}

	/* 获取本机蓝牙适配器状态 */
	getBluetoothState() {
		uni.getBluetoothAdapterState({
			success: (res) => {
				// console.log("状态" + JSON.stringify(res))
			}
		})
	}

	/* 关闭蓝牙适配器*/
	closeBlueAdapter() {
		uni.closeBluetoothAdapter({
			success() {
				// console.log("关闭蓝牙适配器成功")
			}
		})
	}

	/* 断开低功耗蓝牙的连接 */
	disconnectBle() {
		const info = uni.getSystemInfoSync()
		console.log(info)
		if (info.platform === 'android') {
			uni.closeBluetoothAdapter({

				complete: () => {
					uni.closeBLEConnection({
						deviceId: uni.getStorageSync('deviceId'),
						success: (res) => {
							_self.isStop == true
							clearTimeout(_self.timer)
							// console.log("断开成功" + res)
							store.commit('user/UPDATE_STATUS', false);
							// store.commit('setDeviceBattery', 0);
						}
					})
				}

			})
		} else {
			uni.closeBLEConnection({
				deviceId: uni.getStorageSync('deviceId'),
				success: (res) => {
					_self.isStop == true
					clearTimeout(_self.timer)
					// console.log("断开成功" + res)
					store.commit('user/UPDATE_STATUS', false);
					// store.commit('setDeviceBattery', 0);
				}
			})
		}

	}

	/* 具体的命令BCC校验*/
	func(t) {
		for (var e = t, a = [], i = 0; i < e.length - 1; i += 2) a.push(e.substring(i, i + 2));
		for (var o = a[0], s = 0; s < a.length - 1; s++) o ^= a[s + 1];
		return o;
	}

	/* 字符串转arraybuffer */
	string2buffer(str) {
		// 首先将字符串转为16进制
		let val = str
		// console.log(val)
		// 将16进制转化为ArrayBuffer
		return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function(h) {
			return parseInt(h, 16)
		})).buffer
	}
}
